package xj.meta;

/*
 *  left == source
 *  right == destination
 */
public class AssociationElement 
  extends AbstractModelElement 
  implements ModelReference {

  public AssociationElement() {
  }

  public AssociationElement(ModelElement left, ModelElement right) {
    setLeftElement(left);
    setRightElement(right);
  }

  public ModelElement getLeftElement() {
    return left;
  }

  public void setLeftElement(ModelElement left) {
    // System.out.println("AssociationElement.setLeftElement()");

    this.left = left;
    if (left != null) {
      if (refLeft == null) {
	refLeft = new ReferenceElement(left);
      } else {
	refLeft.setReference(left);
      }
    } else {
      refLeft = null;
    }
    setOwnedElement(ROLE_LEFT_REF, refLeft);
  }

  public ModelElement getRightElement() {
    return right;
  }

  public void setRightElement(ModelElement right) {
    // System.out.println("AssociationElement.setRightElement()");

    this.right = right;
    if (right != null) {
      if (refRight == null) {
	refRight = new ReferenceElement(right);
      } else {
	refRight.setReference(right);
      }
    } else {
      refRight = null;
    }
    setOwnedElement(ROLE_RIGHT_REF, refRight);
  }

  public void addReferenceElement(ReferenceElement ref) {
    if (ref != null) {
      String role = ref.getRole();
      if (ROLE_RIGHT_REF.equals(role)) {
	refRight = ref;
	setOwnedElement(role, ref);
      } else if (ROLE_LEFT_REF.equals(role)) {
	refLeft = ref;
	setOwnedElement(role, ref);
      }
    }
  }

  public ReferenceElement getLeftReference() {
    return refLeft;
  }

  public ReferenceElement getRightReference() {
    return refRight;
  }

  public void linkLeftElement() {
    if (left == null && refLeft != null) {
      ModelRepository rep = ModelRepository.getInstance();
      String refid = refLeft.getRefid();
      left = rep.getElement(refid);
    }
  }

  public void linkRightElement() {
    if (right == null && refRight != null) {
      ModelRepository rep = ModelRepository.getInstance();
      String refid = refRight.getRefid();
      right = rep.getElement(refid);
    }
  }

  public void swapEnds() { 
    ModelElement t = left;
    left = right;
    right = t;
    ReferenceElement rt = refLeft;
    refLeft = refRight;
    refRight = rt; 
  }

  public void resolveLink() {
    linkLeftElement();
    linkRightElement();
  }

  @Override
  public Object clone() throws CloneNotSupportedException {
    AssociationElement a = (AssociationElement) super.clone();
    a.left = null; 
    a.right = null;
    a.refLeft = null;
    a.refRight = null;
    a.setLeftElement(left);
    a.setRightElement(right);
    return a;
  }

  public static final String ROLE_LEFT_REF = "leftRef";

  public static final String ROLE_RIGHT_REF = "rightRef";

  protected ModelElement left;

  protected ModelElement right;

  protected ReferenceElement refLeft;

  protected ReferenceElement refRight;

}
